package com.app.security
import com.app.cache.SessionHandler
import com.app.exception.shiro.CaptchaShiroException
import com.app.exception.shiro.PasswordShiroException
import com.app.exception.shiro.UserNameShiroException
import com.app.model.TUser
import com.app.service.user.IUserService
import com.frame.utils.StringUtil
import com.google.code.kaptcha.Constants
import groovy.transform.CompileStatic
import groovy.transform.TypeChecked
import org.apache.shiro.SecurityUtils
import org.apache.shiro.authc.AuthenticationException
import org.apache.shiro.authc.AuthenticationInfo
import org.apache.shiro.authc.AuthenticationToken
import org.apache.shiro.authc.SimpleAuthenticationInfo
import org.apache.shiro.authz.AuthorizationException
import org.apache.shiro.authz.AuthorizationInfo
import org.apache.shiro.authz.SimpleAuthorizationInfo
import org.apache.shiro.realm.AuthorizingRealm
import org.apache.shiro.subject.PrincipalCollection
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
/**
 * Created by three on 14-8-1.
 */
@CompileStatic
@TypeChecked
public class myRealm extends AuthorizingRealm {

    @Value("\${global.channel}")
    private String channelCode

    @Autowired
    private IUserService userService;

    private Logger logger = LoggerFactory.getLogger(myRealm.class);

    public myRealm() {
//        setCredentialsMatcher(new Sha256CredentialsMatcher());
    }

    /**
     * 访问授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        if (principalCollection == null) {
            throw new AuthorizationException("Principal对象不能为空");
        }

//        User user = (User) principals.fromRealm(getName()).iterator().next();
        TUser user = (TUser) getAvailablePrincipal(principalCollection);
        if (user != null) {
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

            //获取用户响应的permission
            List permissions = ["user:write","user:read","user:detail",
                                "user:delete","user:update",
                                "function:list","function:add","function:detail","function:modify","function:delete"
            ];

            info.addStringPermissions(permissions);
            return info;
        } else {
            return null;
        }
    }

    /**
     * 登录授权
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        MyUsernamePasswordToken token = (MyUsernamePasswordToken) authenticationToken;
        String sCode = (String) SecurityUtils.getSubject().getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (sCode.equals(token.getCaptcha())) {
            def params = [:];
            params << ['name': token.getUsername()]
            if (StringUtil.isBlank(token.getUsername())) {
                throw new UserNameShiroException();
            }
            try {
                TUser user = userService.findObj(params as Map);
                if (user == null) {
                    throw new UserNameShiroException();
                }
                if (!user.pwd.equals(String.valueOf(token.getPassword()))) {
                    throw new PasswordShiroException();
                }
                SessionHandler.user(user);
                return new SimpleAuthenticationInfo(user, token.getPassword(), getName());

            } catch (UserNameShiroException e) {
                throw e;
            } catch (PasswordShiroException e) {
                throw e;
            } catch (Exception e) {
                logger.info("登录认证未知异常", e)
                throw e;
            }
        }else{
            throw new CaptchaShiroException();
        }
    }
}
